﻿// Original author contact info: Owen Emlen (owene_1998@yahoo.com)
// Note: other individuals may also have contributed to this code
// Project hosted on CodePlex.com as of 1/10/2009 at http://www.codeplex.com/EmlenMud
using System;
using System.Reflection;
using BrainTechLLC.ThreadSafeObjects;
using LinFu.AOP.Interfaces;

namespace BrainTechLLC
{
	[Serializable, AttributeUsage(AttributeTargets.Method)]
	public class SecurityRestrictionAttribute : Attribute, IReadableAttribute
	{
		public string MethodNameCheckBefore { get; set; }
		public string ExceptionMessage { get; set; }
		public object Value { get { return MethodNameCheckBefore; } }

		public SecurityRestrictionAttribute(string methodNameCheckBefore, string exceptionMessage)
		{
			ExceptionMessage = exceptionMessage;
			MethodNameCheckBefore = methodNameCheckBefore;
		}

		public void DoWorkBefore(IInvocationContext context, object thisObject)
		{
			Type t = thisObject.GetType();

			MethodInfo methodInfo = Lookups.GeneralLookup.Get(t.DotMethodName(MethodNameCheckBefore), v => t.GetMethod(MethodNameCheckBefore));

			bool? result = methodInfo.BoolInvokeIfNotNull(thisObject, context);

			if (result == false)
			{
				throw new Exception("Security Restricted for Method " + context.TargetMethod.Name + ":" +
									String.Format(ExceptionMessage, context.Arguments));
			}
		}
	}
}
